<?php

declare(strict_types = 1);

namespace app\Traits;

use app\common\model\MonthTable;
use think\db\exception\PDOException;

trait AdminBaseFunctionsModel
{
    public function deleteWhere()
    {
        if ( $this->is_delete == 0 ){
            return $this->where($this->delete_field, 0);
        }
        return $this;
    }

    public function getSelectLists(array $where = [], $sort = 'ASC', string $fileds = '*')
    {
        return $this->deleteWhere()
                    ->where($where)
                    ->field($fileds)
                    ->order(is_string($sort) ? [$this->pk => $sort] : $sort)
                    ->select();
    }

    /**
     * 分页列表
     *
     * @param         $model
     * @param  array  $with_model
     * @param  int    $limit
     *
     * @return array
     */
    public function getPaginate(array $params = [], int $limit = 10) : object
    {
        if ( !empty($params['order']) && count($params['order']) >= 2 ) {
            if (isset($params['order'][0])){
                [
                    $field,
                    $sort,
                ] = explode(',', implode(',', $params['order']));
                $params['order'] = [$field => $sort];
            }
        } else {
            $params['order'] = !empty($params['order']) ? [$this->pk => $params['order']] : [$this->pk => 'DESC'];
        }
        // 是否为按月分表的模型进行搜索
        if ($this instanceof MonthTable){
            $model = $this->setMonthTable($params['search_month'] ?? '');
        }else{
            $model = $this;
        }
        $model = $model->deleteWhere()
            ->field(empty($params['field']) ? '*' : $params['field'])
            ->where($params['where'])
            ->with($params['withModel'])
            ->order($params['order']);

        unset($params['where'], $params['order'], $params['withModel']);
        // 分页携带参数
        $list = $model->paginate(['list_rows' => $limit, 'query' => $params]);

        return $list;
    }

    public function detail(int $id, string $filed = '*', bool $lock = false, array $with = [], array $withCount = [])
    {
        return $this->deleteWhere()
                    ->field($filed)
                    ->lock($lock)
                    ->with($with)
                    ->withCount($withCount)
                    ->find($id);
    }

    public function add(array $params = [])
    {
        try {
            $model = $this->create($this->setFilterFields($params));
            $this->setError('插入成功!');
            return $model;
        } catch (PDOException $e) {
            $this->setError($e->getMessage());
            return false;
        }
    }

    public function edit(array $params = [], array $where = [])
    {
        try {
            $primary = $params[$this->pk];
            $res = $this->where($this->pk, $primary)->update($this->setFilterFields($params));
            $this->setError('更新成功!');
            return $res;
        } catch (PDOException $e) {
            $this->setError($e->getMessage());
            return false;
        }
    }

    public function dataDelete(array $params = [], array $where = [])
    {
        if ( empty($params[$this->pk]) && empty($params['is_batch'])) {
            $this->setError('主键为必填项！');
            return false;
        }
        /**
         * 如果是月份表进行删除的话，那么需要指定表名
         */
        if ($this instanceof MonthTable && isset($params['month'])){
            $model = $this->setMonthTable($params['month']);
        }else{
            $model = $this;
        }
        if (empty($params[$this->pk])){ // 是否为批量删除
            $ids = $params['ids'];

            $alert_prefix = '{ ' . $this->pk . ' => ' . my_json_encode($ids) . ' }';
        }else{
            $ids = $params[$this->pk];

            $alert_prefix = '{ ' . $this->pk . ' => ' . $ids . ' }';
            if ( empty($this_model = $model->deleteWhere()->where($where)->find($params[$this->pk])) ) {
                $this->setError($alert_prefix . '不存在！');
                return false;
            }
            $ids = [$ids];
        }

        switch (intval($this->is_delete)) {
            case 0:
                $operating_state = $model->deleteWhere()->whereIn($this->pk, $ids)->update([$this->delete_field => 1]);
                break;
            case 1:
                $operating_state = $model->deleteWhere()->whereIn($this->pk, $ids)->delete();
                break;
        }
        if ( $operating_state ) {
            $this->setError($alert_prefix . '删除成功！');
            return true;
        } else {
            $this->setError($alert_prefix . '删除失败！');
            return false;
        }
    }

    public function changeFiledStatus(array $params = [], array $where = [])
    {
        if ( empty($params[$this->pk]) ) {
            $this->setError('主键为必填项！');
            return false;
        }
        $alert_prefix = '{ ' . $this->pk . ' => ' . $params[$this->pk] . ' }';
        if ( empty($this_model = $this->deleteWhere()->where($where)->find($params[$this->pk])) ) {
            $this->setError($alert_prefix . '不存在！');
            return false;
        }
        if ( $this->deleteWhere()->where([$this->pk => $params[$this->pk]])->update([$params['change_field'] => $params['change_value']]) ) {
            $this->setError($alert_prefix . '设置成功！');
            return true;
        } else {
            $this->setError($alert_prefix . '设置失败！');
            return false;
        }
    }

    /**
     * 过滤录入数据表时，移除非表字段的数据
     *
     * @param $params
     *
     * @return array
     */
    protected function setFilterFields(array $params) : array
    {
        $fields = $this->db(false)
                       ->getConnection()
                       ->getTableFields($this->getTable());
        foreach ($params as $key => $param) {
            if ( !in_array($key, $fields) ) unset($params[$key]);
        }
        // 同时过滤时间戳字段【时间戳只允许自动更改，不允许手动设置】
        if ( $this->autoWriteTimestamp === true && isset($params[$this->createTime]) ) unset($params[$this->createTime]);
        if ( $this->autoWriteTimestamp === true && isset($params[$this->updateTime]) ) unset($params[$this->updateTime]);
        return $params;
    }

    public function batchExport()
    {
        var_dump(TEMP_PATH);
    }
}
